package com.rex.saas.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.rex.saas.bean.*;
import com.rex.saas.bean.request.PriceDetailsRequest;
import com.rex.saas.bean.request.SpaceAddRequest;
import com.rex.saas.bean.request.SpacePriceRequest;
import com.rex.saas.bean.response.SpaceDetailResponse;
import com.rex.saas.bean.response.SpacePriceDetailsResponse;
import com.rex.saas.constants.Constants;
import com.rex.saas.db.entity.*;
import com.rex.saas.db.mapper.*;
import com.rex.saas.enums.StatusEnum;
import com.rex.saas.enums.SpaceTypeEnum;
import com.rex.saas.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@Slf4j
public class SpaceService {
    @Autowired
    private SaasSpaceInfoMapper saasSpaceInfoMapper;

    @Autowired
    private SaasSpacePriceMapper saasSpacePriceMapper;

    @Autowired
    private SaasSpacePriceDetailsMapper saasSpacePriceDetailsMapper;

    @Autowired
    private SaasSpaceDeviceRelationMapper saasSpaceDeviceRelationMapper;

    @Autowired
    private SaasSpaceStatisticsMapper saasSpaceStatisticsMapper;


    @Autowired
    private RexolarApiClient rexolarApiClient;


    public List<SaasSpaceInfo> getSpaceByName(String name, String tenantId) {
        LambdaQueryWrapper<SaasSpaceInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaasSpaceInfo::getName, name);
        queryWrapper.eq(SaasSpaceInfo::getTenantId, tenantId);
        queryWrapper.eq(SaasSpaceInfo::getStatus, StatusEnum.ENABLE.getCode());
        return saasSpaceInfoMapper.selectList(queryWrapper);
    }

    public SaasSpaceInfo getSpaceById(Long id) {
        return saasSpaceInfoMapper.selectById(id);
    }

    public Long addCustomerSpace(SpaceAddRequest spaceAddRequest, String token) {
        String tenantToken = rexolarApiClient.getTenantToken(JwtUtils.getTenantId(token));
        String profileId = rexolarApiClient.getAssetDefaultProfileId(tenantToken);
        if (profileId == null) {
            log.error("getAssetDefaultProfileId error!!!!");
            return null;
        }
        String coreId = rexolarApiClient.dynamicCreateAsset(spaceAddRequest.getSpaceName(), profileId, tenantToken);
        if (coreId == null) {
            log.error("dynamicCreateAsset error, spaceName:{}", spaceAddRequest.getSpaceName());
            return null;
        }

        boolean flag = rexolarApiClient.bindCustomerToAsset(coreId, JwtUtils.getCustomerId(token), tenantToken);
        if (!flag) {
            log.error("bindCustomerToAsset error, spaceInfoId:{}", coreId);
            return null;
        }

        SaasSpaceInfo saasSpaceInfo = new SaasSpaceInfo();
        saasSpaceInfo.setCoreId(coreId);
        saasSpaceInfo.setTenantId(JwtUtils.getTenantId(token));
        saasSpaceInfo.setCustomerId(JwtUtils.getCustomerId(token));
        saasSpaceInfo.setName(spaceAddRequest.getSpaceName());
        saasSpaceInfo.setType(SpaceTypeEnum.POWER_MONITORING.getCode());
        saasSpaceInfo.setStatus(StatusEnum.ENABLE.getCode());
        saasSpaceInfo.setGmtCreated(new Date());
        saasSpaceInfo.setGmtModified(new Date());
        if(saasSpaceInfoMapper.insert(saasSpaceInfo)!=1){
            log.error("insert saasSpaceInfo error, saasSpaceInfo:{}", saasSpaceInfo);
            return null;
        }
        return saasSpaceInfo.getId();
    }
    public boolean configCtSpace(SaasSpaceInfo spaceInfo) {
        spaceInfo.setGmtModified(new Date());
        if(saasSpaceInfoMapper.updateById(spaceInfo)==1){
            log.info("configCtSpace updateById success, spaceInfo:{}", spaceInfo);
            return true;
        }else {
            log.error("configCtSpace updateById error, spaceInfo:{}", spaceInfo);
            return false;
        }
    }

    public void deleteSpaceByUser(String token) {
        LambdaQueryWrapper<SaasSpaceInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaasSpaceInfo::getTenantId, JwtUtils.getTenantId(token));
        queryWrapper.eq(SaasSpaceInfo::getCustomerId, JwtUtils.getCustomerId(token));
        List<SaasSpaceInfo> saasSpaceInfos = saasSpaceInfoMapper.selectList(queryWrapper);
        for (SaasSpaceInfo saasSpaceInfo : saasSpaceInfos){
            LambdaQueryWrapper<SaasSpaceStatistics> saasSpaceStatisticsLambdaQueryWrapper = new LambdaQueryWrapper<>();
            saasSpaceStatisticsLambdaQueryWrapper.eq(SaasSpaceStatistics::getSpaceId, saasSpaceInfo.getId());
            saasSpaceStatisticsMapper.delete(saasSpaceStatisticsLambdaQueryWrapper);

            LambdaQueryWrapper<SaasSpaceDeviceRelation> deviceQueryWrapper = new LambdaQueryWrapper<>();
            deviceQueryWrapper.eq(SaasSpaceDeviceRelation::getSpaceId, saasSpaceInfo.getCoreId());
            deviceQueryWrapper.eq(SaasSpaceDeviceRelation::getTenantId, JwtUtils.getTenantId(token));
            saasSpaceDeviceRelationMapper.delete(deviceQueryWrapper);

            rexolarApiClient.deleteAsset(saasSpaceInfo.getCoreId(), rexolarApiClient.getTenantToken(JwtUtils.getTenantId(token)));
            saasSpaceInfoMapper.deleteById(saasSpaceInfo.getId());
        }
    }

    public boolean bindCustomerDevices(SaasSpaceInfo space, List<DeviceRelationInfo> devices, String token) {
        String tenantToken = rexolarApiClient.getTenantToken(JwtUtils.getTenantId(token));
        for (DeviceRelationInfo deviceRelationInfo : devices) {
            DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(deviceRelationInfo.getDeviceName(), tenantToken);
            if(deviceBasicData==null){
                log.error("bindCustomerDevices space getDeviceByDeviceName error, deviceName:{}", deviceRelationInfo.getDeviceName());
                return false;
            }
            boolean result = rexolarApiClient.addRelationsInfo(tenantToken, space.getCoreId(), "ASSET", "Contains", deviceBasicData.getCoreId(), "DEVICE");
            if(!result){
                log.error("bindCustomerDevices addRelationsInfo error, deviceName:{}", deviceRelationInfo.getDeviceName());
                return false;
            }
            LambdaQueryWrapper<SaasSpaceDeviceRelation> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SaasSpaceDeviceRelation::getDeviceName, deviceRelationInfo.getDeviceName());
            queryWrapper.eq(SaasSpaceDeviceRelation::getSpaceInfoId, space.getId());
            List<SaasSpaceDeviceRelation> relations = saasSpaceDeviceRelationMapper.selectList(queryWrapper);
            if (!CollectionUtils.isEmpty( relations)){
                SaasSpaceDeviceRelation tmp = relations.get(0);
                if(tmp.getType().equals(deviceRelationInfo.getType())){
                    log.info("bindCustomerDevices type is same, skip, deviceName:{}", deviceRelationInfo.getDeviceName());
                    continue;
                }else {
                    saasSpaceDeviceRelationMapper.delete(queryWrapper);
                }
            }

            SaasSpaceDeviceRelation saasSpaceDeviceRelation = new SaasSpaceDeviceRelation();
            saasSpaceDeviceRelation.setSpaceId(space.getCoreId());
            saasSpaceDeviceRelation.setSpaceInfoId(space.getId());
            saasSpaceDeviceRelation.setDeviceName(deviceRelationInfo.getDeviceName());
            saasSpaceDeviceRelation.setType(deviceRelationInfo.getType());
            saasSpaceDeviceRelation.setTenantId(JwtUtils.getTenantId(token));
            saasSpaceDeviceRelation.setCustomerId(JwtUtils.getCustomerId(token));
            if(saasSpaceDeviceRelationMapper.insert(saasSpaceDeviceRelation)!=1){
                log.error("bindCustomerDevices insert saasSpaceDeviceRelation error, saasSpaceDeviceRelation:{}", saasSpaceDeviceRelation);
                return false;
            }
        }
        return true;
    }

    public Boolean configPrice(SpacePriceRequest spacePriceRequest) {
        List<SaasSpacePrice> list = saasSpacePriceMapper
                .selectList(new LambdaQueryWrapper<SaasSpacePrice>().eq(SaasSpacePrice::getSpaceId, spacePriceRequest.getSpaceId())
                        .orderByDesc(SaasSpacePrice::getGmtCreated));
        if (CollectionUtils.isEmpty(list)){
            SaasSpacePrice saasSpacePrice = new SaasSpacePrice();
            BeanUtils.copyProperties(spacePriceRequest, saasSpacePrice);
            return saasSpacePriceMapper.insert(saasSpacePrice)==1;
        }else {
            SaasSpacePrice saasSpacePrice = list.get(0);
            saasSpacePrice.setOutPrice(spacePriceRequest.getOutPrice());
            saasSpacePrice.setImportPrice(spacePriceRequest.getImportPrice());
            saasSpacePrice.setGmtModified(new Date());
            return saasSpacePriceMapper.updateById(saasSpacePrice)==1;
        }
    }

    public List<SaasSpaceDeviceRelation> getCustomerDeviceList(Long id, String customerId) {
        LambdaQueryWrapper<SaasSpaceDeviceRelation> queryWarper = new LambdaQueryWrapper<SaasSpaceDeviceRelation>();
        queryWarper.eq(SaasSpaceDeviceRelation::getSpaceInfoId, id);
        queryWarper.eq(SaasSpaceDeviceRelation::getCustomerId, customerId);
        return saasSpaceDeviceRelationMapper.selectList(queryWarper);
    }

    public SaasSpacePrice getSpacePrice(Long id) {
        LambdaQueryWrapper<SaasSpacePrice> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaasSpacePrice::getSpaceId, id);
        queryWrapper.orderByDesc(SaasSpacePrice::getGmtCreated);
        List<SaasSpacePrice> prices = saasSpacePriceMapper.selectList(queryWrapper);
        if(CollectionUtils.isEmpty(prices)){
            return null;
        }
        return prices.get(0);
    }

    public SaasSpacePrice getSpacePriceById(Long priceId) {
        return saasSpacePriceMapper.selectById(priceId);
    }

    public SaasSpacePriceDetails getSpacePriceDetailsById(Long priceId) {
        return saasSpacePriceDetailsMapper.selectById(priceId);
    }

    public List<SaasSpaceInfo> getCustomerSpaceList(String token) {
        LambdaQueryWrapper<SaasSpaceInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaasSpaceInfo::getTenantId, JwtUtils.getTenantId(token));
        queryWrapper.eq(SaasSpaceInfo::getCustomerId, JwtUtils.getCustomerId(token));
        queryWrapper.eq(SaasSpaceInfo::getStatus, StatusEnum.ENABLE.getCode());
        return saasSpaceInfoMapper.selectList(queryWrapper);
    }

    public SpacePowerData getSpacePower(SaasSpaceInfo saasSpaceInfo) {
        SpacePowerData spacePowerData = new SpacePowerData();
        spacePowerData.setSpaceId(saasSpaceInfo.getId());
        spacePowerData.setSpaceName(saasSpaceInfo.getName());
        LambdaQueryWrapper<SaasSpaceDeviceRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaasSpaceDeviceRelation::getSpaceId, saasSpaceInfo.getCoreId());
        queryWrapper.eq(SaasSpaceDeviceRelation::getTenantId, saasSpaceInfo.getTenantId());
        List<SaasSpaceDeviceRelation> relations = saasSpaceDeviceRelationMapper.selectList(queryWrapper);
        if(!CollectionUtils.isEmpty(relations)){
            String tenantToken = rexolarApiClient.getTenantToken(saasSpaceInfo.getTenantId());
            if(StringUtils.isEmpty(tenantToken)){
                log.error("getSpacePower getTenantToken error, tenantId:{}", saasSpaceInfo.getTenantId());
                return null;
            }
            for (SaasSpaceDeviceRelation saasSpaceDeviceRelation : relations) {
                DeviceBasicData deviceBasicData = rexolarApiClient.getDeviceByDeviceName(saasSpaceDeviceRelation.getDeviceName(), tenantToken);
                if(deviceBasicData==null){
                    log.error("getSpacePower space getDeviceByDeviceName error, saasSpaceDeviceRelation.deviceName:{}", saasSpaceDeviceRelation.getDeviceName());
                    continue;
                }
                Map<String, Object> deviceAttributes = rexolarApiClient.getDeviceAttributes(deviceBasicData.getCoreId(), tenantToken, new String[]{Constants.ACTIVE});
                if (deviceAttributes == null || "false".equals(deviceAttributes.get(Constants.ACTIVE).toString())) {
                    log.error("getSpacePower device active is false, saasSpaceDeviceRelation.deviceName:{}", saasSpaceDeviceRelation.getDeviceName());
                    continue;
                }
                Map<String, List<DeviceTimeSeries>> timeSeriesLatest = rexolarApiClient.getDeviceTimeSeriesLatest(
                        deviceBasicData.getCoreId(), tenantToken, new String[]{Constants.ActivePower_1,
                                Constants.TotalActivePower_1,Constants.TotalCEI_1,Constants.TotalCEE_1}, false);
                if(CollectionUtils.isEmpty(timeSeriesLatest)){
                    log.warn("getSpacePower getDeviceTimeSeriesLatest is empty, deviceName:{}", saasSpaceDeviceRelation.getDeviceName());
                    continue;
                }
                if(saasSpaceDeviceRelation.getType()== Constants.CT_IN){
                    if(timeSeriesLatest.get(Constants.TotalActivePower_1)!=null){
                        JSONObject timeSeries = timeSeriesLatest.get(Constants.TotalActivePower_1).get(0);
                        spacePowerData.setSpaceGridPower(spacePowerData.getSpaceGridPower() +  timeSeries.getFloat("value"));
                    }
                }else if(saasSpaceDeviceRelation.getType()== Constants.CT_OUT){
                    if(timeSeriesLatest.get(Constants.TotalActivePower_1)!=null){
                        JSONObject timeSeries = timeSeriesLatest.get(Constants.TotalActivePower_1).get(0);
                        spacePowerData.setSpacePhotovoltaicPower(spacePowerData.getSpacePhotovoltaicPower() + timeSeries.getFloat("value"));
                    }
                }else if(saasSpaceDeviceRelation.getType()== Constants.CT_SOCKET){
                    if(timeSeriesLatest.get(Constants.ActivePower_1)!=null){
                        JSONObject timeSeries = timeSeriesLatest.get(Constants.ActivePower_1).get(0);
                        spacePowerData.setSpaceGridPower(spacePowerData.getSpaceGridPower() + timeSeries.getFloat("value"));
                    }
                }else {
                    log.error("getSpacePower type error, saasSpaceDeviceRelation :{}", saasSpaceDeviceRelation);
                }
            }
            spacePowerData.setSpaceLoadPower(Float.sum(Math.abs(spacePowerData.getSpacePhotovoltaicPower()), spacePowerData.getSpaceGridPower()));
        }
        return spacePowerData;
    }

    public Boolean setDefault(SaasSpaceInfo space, String token) {
        LambdaQueryWrapper<SaasSpaceInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaasSpaceInfo::getTenantId, JwtUtils.getTenantId(token));
        queryWrapper.eq(SaasSpaceInfo::getCustomerId, JwtUtils.getCustomerId(token));
        queryWrapper.eq(SaasSpaceInfo::getIsDefault, true);
        List<SaasSpaceInfo> list = saasSpaceInfoMapper.selectList(queryWrapper);
        for (SaasSpaceInfo saasSpaceInfo : list){
            saasSpaceInfo.setIsDefault(false);
            saasSpaceInfoMapper.updateById(saasSpaceInfo);
        }
        space.setIsDefault(true);
        space.setGmtModified(new Date());
        return saasSpaceInfoMapper.updateById(space) == 1;
    }

    public List<SaasSpaceInfo> getAllList() {
        LambdaQueryWrapper<SaasSpaceInfo> queryWrapper = new LambdaQueryWrapper<>();
        return saasSpaceInfoMapper.selectList(queryWrapper);
    }

    public List<SaasSpaceDeviceRelation> getSpaceByDeviceName(String deviceName) {
        LambdaQueryWrapper<SaasSpaceDeviceRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaasSpaceDeviceRelation::getDeviceName, deviceName);
        return saasSpaceDeviceRelationMapper.selectList(queryWrapper);
    }

    public List<SpacePriceDetailsResponse> priceDetails(Long spacePriceId) {
        List<SpacePriceDetailsResponse> spacePriceDetailsResponses = new ArrayList<>();
        List<SaasSpacePriceDetails> details = saasSpacePriceDetailsMapper.selectList(
                new LambdaQueryWrapper<SaasSpacePriceDetails>().eq(SaasSpacePriceDetails::getSpacePriceId, spacePriceId));
        for (SaasSpacePriceDetails detail : details) {
            SpacePriceDetailsResponse spacePriceDetailsResponse = new SpacePriceDetailsResponse();
            BeanUtils.copyProperties(detail, spacePriceDetailsResponse);
            spacePriceDetailsResponses.add(spacePriceDetailsResponse);
        }
        return spacePriceDetailsResponses;
    }

    public Boolean addPriceDetails(PriceDetailsRequest priceDetailsRequest) {
        SaasSpacePriceDetails saasSpacePriceDetails = new SaasSpacePriceDetails();
        saasSpacePriceDetails.setSpacePriceId(priceDetailsRequest.getSpacePriceId());
        saasSpacePriceDetails.setStartDate(priceDetailsRequest.getStartDate());
        saasSpacePriceDetails.setEndDate(priceDetailsRequest.getEndDate());
        saasSpacePriceDetails.setStartTime(priceDetailsRequest.getStartTime());
        saasSpacePriceDetails.setEndTime(priceDetailsRequest.getEndTime());
        saasSpacePriceDetails.setImportPrice(priceDetailsRequest.getImportPrice());
        saasSpacePriceDetails.setOutPrice(priceDetailsRequest.getOutPrice());
        saasSpacePriceDetails.setGmtCreated(new Date());
        saasSpacePriceDetails.setGmtModified(new Date());
        return saasSpacePriceDetailsMapper.insert(saasSpacePriceDetails) == 1;
    }

    public boolean deletePriceDetails(Long priceDetailsId) {
        return saasSpacePriceDetailsMapper.deleteById(priceDetailsId) == 1;
    }

    public SpaceDetailResponse detail(Long spaceId) {
        SaasSpaceInfo spaceInfo = saasSpaceInfoMapper.selectById(spaceId);
        if (spaceInfo == null){
            log.error("detail space is not exist, spaceId:{}", spaceId);
            return null;
        }
        SpaceDetailResponse spaceDetailResponse = new SpaceDetailResponse();
        spaceDetailResponse.setSpaceId(spaceInfo.getId());
        spaceDetailResponse.setSpaceName(spaceInfo.getName());
        return spaceDetailResponse;
    }

    public List<SaasSpacePrice> getSpacePriceBySpaceId(Long spaceId) {
        return saasSpacePriceMapper.selectList(new LambdaQueryWrapper<SaasSpacePrice>().eq(SaasSpacePrice::getSpaceId, spaceId));
    }

    public List<SaasSpacePriceDetails> getSpacePriceDetailsByPriceId(Long id) {
        return saasSpacePriceDetailsMapper.selectList(new LambdaQueryWrapper<SaasSpacePriceDetails>().eq(SaasSpacePriceDetails::getSpacePriceId, id));
    }

    public List<SpaceInfo> list(String tenantId) {
        List<SpaceInfo> spaceInfos = new ArrayList<>();
        List<SaasSpaceInfo> list = saasSpaceInfoMapper.selectList(new LambdaQueryWrapper<SaasSpaceInfo>().eq(SaasSpaceInfo::getTenantId, tenantId));
        for (SaasSpaceInfo saasSpaceInfo : list){
            SpaceInfo spaceInfo = new SpaceInfo();
            BeanUtils.copyProperties(saasSpaceInfo, spaceInfo);
            spaceInfo.setGmtCreated(saasSpaceInfo.getGmtCreated().getTime());
            spaceInfo.setGmtModified(saasSpaceInfo.getGmtModified().getTime());
            spaceInfos.add(spaceInfo);
        }
        return spaceInfos;
    }

    public Long add(String spaceName, String token) {
        String profileId = rexolarApiClient.getAssetDefaultProfileId(token);
        if (profileId == null) {
            log.error("add, getAssetDefaultProfileId error!!!!");
            return null;
        }
        String coreId = rexolarApiClient.dynamicCreateAsset(spaceName, profileId, token);
        if (coreId == null) {
            log.error("add, dynamicCreateAsset error, spaceName:{}", spaceName);
            return null;
        }

        SaasSpaceInfo saasSpaceInfo = new SaasSpaceInfo();
        saasSpaceInfo.setCoreId(coreId);
        saasSpaceInfo.setTenantId(JwtUtils.getTenantId(token));
        saasSpaceInfo.setName(spaceName);
        saasSpaceInfo.setType(SpaceTypeEnum.POWER_MONITORING.getCode());
        saasSpaceInfo.setStatus(StatusEnum.ENABLE.getCode());
        saasSpaceInfo.setGmtCreated(new Date());
        saasSpaceInfo.setGmtModified(new Date());
        if(saasSpaceInfoMapper.insert(saasSpaceInfo)!=1){
            log.error("insert saasSpaceInfo error, saasSpaceInfo:{}", saasSpaceInfo);
            return null;
        }
        return saasSpaceInfo.getId();
    }

    public boolean delete(Long spaceId, String token) {
        LambdaQueryWrapper<SaasSpaceDeviceRelation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaasSpaceDeviceRelation::getSpaceInfoId, spaceId);
        saasSpaceDeviceRelationMapper.delete(queryWrapper);
        LambdaQueryWrapper<SaasSpacePrice> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(SaasSpacePrice::getSpaceId, spaceId);
        saasSpacePriceMapper.delete(queryWrapper1);
        LambdaQueryWrapper<SaasSpacePriceDetails> queryWrapper2 = new LambdaQueryWrapper<>();
        queryWrapper2.eq(SaasSpacePriceDetails::getSpacePriceId, spaceId);
        saasSpacePriceDetailsMapper.delete(queryWrapper2);
        LambdaQueryWrapper<SaasSpaceStatistics> queryWrapper3 = new LambdaQueryWrapper<SaasSpaceStatistics>()
                .eq(SaasSpaceStatistics::getSpaceId, spaceId);
        saasSpaceStatisticsMapper.delete(queryWrapper3);
        return saasSpaceInfoMapper.deleteById(spaceId) == 1;
    }

    public List<String> getDeviceNameList(Long spaceId) {
        return saasSpaceDeviceRelationMapper.selectList(new LambdaQueryWrapper<SaasSpaceDeviceRelation>().eq(SaasSpaceDeviceRelation::getSpaceInfoId, spaceId))
                .stream().map(SaasSpaceDeviceRelation::getDeviceName).collect(Collectors.toList());
    }

    public String getPositionInfo(Long spaceId, String deviceName) {
        List<SaasSpaceDeviceRelation> list = saasSpaceDeviceRelationMapper.selectList(new LambdaQueryWrapper<SaasSpaceDeviceRelation>()
                .eq(SaasSpaceDeviceRelation::getSpaceInfoId, spaceId)
                .eq(SaasSpaceDeviceRelation::getDeviceName, deviceName));
        if(CollectionUtils.isEmpty( list)){
            return null;
        }
        return list.get(0).getPosition();
    }
}
